home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-04-25 | 13.4 KB | 476 lines | [TEXT/CWIE] |
- // ==================================================
- // CTouchMeMainWindowDD.cp
- // a part of CTouchMeMainWindow.cp
- // Copyright (C) 1996-1997 Mizutori Tetsuya
- // July 4, 1996; August 4, 1996; February 3, 1997; April 24, 1997.
- // ==================================================
- // All documents are pretty-printed in 10-point Geneva font.
-
- #include <LPane.h>
- #include <LDragTask.h>
- #include <UDrawingState.h>
- #include <UDrawingUtils.h>
- #include <LBroadcaster.h>
- #include <LCommander.h>
-
- #include <PP_Messages.h>
-
- #include "touchMeConstants.h"
- #include "CTouchMeMainWindow.h"
- #include "CTouchMeMainWindowDD.h"
- #include "CDateEditField.h"
- #include "CFlavor.h"
- #include "UFileTools.h"
- #include "UDragDropSuit.h"
-
-
- #ifdef COMMENT
- enum {
- flavorTypeHFS = 'hfs ',
- flavorTypePromiseHFS = 'phfs',
- flavorTypeDirectory = 'diry'
- };
-
- typedef struct HFSFlavor {
- OSType fileType;
- OSType fileCreator;
- unsigned short fdFlags;
- FSSpec fileSpec;
- } HFSFlavor;
- #endif // COMMENT
-
- const FlavorType flavorTypeText = 'TEXT';
-
- const PaneIDT thePaneList[] = {
- kMain_CrTextEditDate,
- kMain_CrTextEditTime,
- kMain_MdTextEditDate,
- kMain_MdTextEditTime,
- kNoPaneID };
-
-
- // ==================================================
- // Drag and Drop
- // ==================================================
-
- // --------------------------------------------------
- // • ItemIsAcceptable
- // --------------------------------------------------
- // Accept 'TEXT' or HFS-type files, which are dragged from Finder.
-
- Boolean
- CTouchMeMainWindow::ItemIsAcceptable(
- DragReference inDragRef,
- ItemReference inItemRef )
- {
- FlavorFlags theFlags;
-
- // Accept HFS-type files, which are dragged from Finder.
- if ( IsEnabled() &&
- (::GetFlavorFlags( inDragRef, inItemRef, flavorTypeHFS, &theFlags ) == noErr) ) {
- mTextDrag = false;
- return true;
- }
-
- // Accept 'TEXT' type, which are dragged from Finder.
- if ( IsEnabled() &&
- (::GetFlavorFlags( inDragRef, inItemRef, flavorTypeText, &theFlags ) == noErr) ) {
- mTextDrag = true;
- return true;
- }
-
- return false;
- }
-
-
- // --------------------------------------------------
- // • ReceiveDragItem
- // --------------------------------------------------
-
- void
- CTouchMeMainWindow::ReceiveDragItem(
- DragReference inDragRef,
- DragAttributes inDragAttrs,
- ItemReference inItemRef,
- Rect & inItemBounds )
- {
- #pragma unused ( inDragAttrs, inItemBounds )
- // OSErr err;
-
- if ( mTextDrag ) {
- mTextDrag = false;
- if ( UDragDropSuit::InDragRegion( inDragRef ) )
- Throw( dragNotAcceptedErr );
- }
-
- // Get the flavor data.
- CFlavor theFlavor( inDragRef, inItemRef );
-
- switch ( theFlavor.mType ) {
- case flavorTypeHFS:
- {
- FSSpec theFSSpec = theFlavor.mFSSpec;
- if ( ! mModifier ) {
- // if ( ! IsModifierKeyPressed( inDragRef ) ) {
-
- // Do execute 'touch' theFSSpec, if the option-key is not pressed.
- ProcessCommand( msg_Touch, (void *) &theFSSpec );
-
- } else {
-
- // If the option-key is pressed,
- // Set date time EditFields by the stamp of theFSSpec, if no modifier key is pressed.
- // If the file was dropped on some EditField, then the only one EditField will be changed.
- // Now, get the mouse location and convert to port coordinates.
- Point thePoint;
- ::GetDragMouse( inDragRef, &thePoint, NULL );
- GlobalToPortPoint( thePoint );
- PaneIDT thePaneID = FindPaneByMouse( thePoint );
-
- switch ( thePaneID ) {
- case kMain_CrTextEditDate:
- BroadcastMessage( msg_Main_DroppedFileCrDate, (void *) &theFSSpec );
- break;
- case kMain_CrTextEditTime:
- BroadcastMessage( msg_Main_DroppedFileCrTime, (void *) &theFSSpec );
- break;
- case kMain_MdTextEditDate:
- BroadcastMessage( msg_Main_DroppedFileMdDate, (void *) &theFSSpec );
- break;
- case kMain_MdTextEditTime:
- BroadcastMessage( msg_Main_DroppedFileMdTime, (void *) &theFSSpec );
- break;
- default:
- BroadcastMessage( msg_Main_DroppedFile, (void *) &theFSSpec ); break;
- }
-
- }
- }
- break;
-
- case flavorTypeText:
- {
- // Set date time EditFields by the dropped 'TEXT' string.
- // If the 'TEXT' was dropped on some EditField, then the only one EditField will be changed.
- // Now, get the mouse location and convert to port coordinates.
- Handle theTextH = theFlavor.mTextH;
- long theTextLen = theFlavor.mTextLen;
- Str255 theString;
- theString[0] = theTextLen;
- ::BlockMoveData( *theTextH, &theString[1], theString[0] );
-
- Point thePoint;
- ::GetDragMouse( inDragRef, &thePoint, NULL );
- GlobalToPortPoint( thePoint );
- PaneIDT thePaneID = FindPaneByMouse( thePoint );
-
- switch ( thePaneID ) {
- case kMain_CrTextEditDate:
- BroadcastMessage( msg_Main_DroppedTextCrDate, (void *) theString );
- break;
- case kMain_CrTextEditTime:
- BroadcastMessage( msg_Main_DroppedTextCrTime, (void *) theString );
- break;
- case kMain_MdTextEditDate:
- BroadcastMessage( msg_Main_DroppedTextMdDate, (void *) theString );
- break;
- case kMain_MdTextEditTime:
- BroadcastMessage( msg_Main_DroppedTextMdTime, (void *) theString );
- break;
- default:
- // Do zoom back rect bounds if the drag was failed.
- // UDragDropSuit::ZoomBackBounds( inDragRef, inItemRef );
- // Instead of zooming rects by myself, we throw error exception
- // to LDragAndDrop::DoDragReceive, which will cancel Finder's trace drag.
- Throw( dragNotAcceptedErr );
- break;
- }
- }
- break;
-
- default:
- ThrowOSErr_( badDragFlavorErr );
- break;
- }
-
- }
-
-
- // --------------------------------------------------
- // • EnterDropArea
- // --------------------------------------------------
-
- void
- CTouchMeMainWindow::EnterDropArea(
- DragReference inDragRef,
- Boolean inDragHasLeftSender )
- {
- #pragma unused (inDragHasLeftSender)
-
- // True if the dragged item is a text from my text edit field.
- mTextDrag = mTextDrag || UDragDropSuit::InDragRegion( inDragRef );
-
- // Check the status of modifier keys, whether it is pressed or not.
- mModifier = IsModifierKeyPressed( inDragRef );
-
- // Invalidate the last hilite pane.
- mHilitePaneID = kNoPaneID;
-
- // Before ::ShowDragHilite() and ::HideDragHilite(), we must seup the graf port status
- // by calling ApplyForeAndBackColors(). This is needed because we have changed our
- // background color of the window.
- FocusDropArea();
- ApplyForeAndBackColors();
-
- // Call inherited.
- LDragAndDrop::EnterDropArea( inDragRef, inDragHasLeftSender || mTextDrag );
-
- // Remember the last (latent) target before a drag & drop operation.
- // mTargetID = kNoPaneID; // This time, we do not use ID number.
- mTarget = NULL;
-
- // Get the EditField as a target commander among four EditFields.
- // If the dialog is in front, then 'GetTarget()' returns the target EditField.
- // If it is not in front or in background, then the dialog itself is a latent sub commander,
- // so that the desired EditField is to be get by 'GetLatentSub()' of the dialog.
- LCommander * theTarget = GetTarget();
- LCommander * theLatentTarget = GetLatentSub();
- if ( theLatentTarget != NULL )
- theTarget = theLatentTarget->GetLatentSub();
-
- if ( theTarget != NULL ) {
- // If a target exists, it must be an EditField and then should be deactivated.
- // You can confirm which the target is a type of EditField, as follows.
- // PaneIDT iPaneID, iTargetPaneID;
- // iTargetPaneID = ((CDateEditField *) theTarget)->GetPaneID();
- // Boolean found=false;
- // for ( short i=0; (iPaneID=thePaneList[i]) != kNoPaneID; i++ )
- // if ( iTargetPaneID == iPaneID ) { found=true; }
- // if ( found ) mTargetID = iTargetPaneID;
- mTarget = theTarget;
- // Let's deactivate the TE field because the hilite color can be
- // distinguished between colors by selection and HiliteRect().
- mTEActive = ((CDateEditField *) theTarget)->GetTEActive();
- // Check if it is a dragging text or not.
- if ( ! mTextDrag ) ((CDateEditField *) theTarget)->SetTEActive( false );
- }
- }
-
-
- // --------------------------------------------------
- // • LeaveDropArea
- // --------------------------------------------------
-
- void
- CTouchMeMainWindow::LeaveDropArea(
- DragReference inDragRef )
- {
- // Before ::ShowDragHilite() and ::HideDragHilite(), we must seup the graf port status
- // by calling ApplyForeAndBackColors(). This is needed because we have changed our
- // background color of the window.
- // FocusDropArea();
- // ApplyForeAndBackColors();
-
- // Check the status of modifier keys, which is pressed or not.
- // mModifier = false;
- // mTextDrag = false;
-
- // Invalidate the last hilite pane.
- HilitePane( mHilitePaneID );
- mHilitePaneID = kNoPaneID;
-
- // Restore the last (latent) target before a drag & drop operation.
- // if ( mTargetID != kNoPaneID ) { // This time, we do not use ID number.
- if ( mTarget != NULL ) {
- // LCommander * theTarget = (LCommander *) FindPaneByID( mTargetID );
- // SwitchTarget( theTarget );
- ((CDateEditField *) mTarget)->SetTEActive( mTEActive );
- }
- // mTargetID = kNoPaneID;
- mTarget = NULL;
-
- // Call inherited.
- LDragAndDrop::LeaveDropArea( inDragRef );
- }
-
-
- // --------------------------------------------------
- // • InsideDropArea
- // --------------------------------------------------
-
- void
- CTouchMeMainWindow::InsideDropArea(
- DragReference inDragRef )
- {
- // Call inherited.
- LDragAndDrop::InsideDropArea( inDragRef );
-
- // If option-key is not pressed, then hilite area is the bound of this dialog box.
- // if ( ! IsModifierKeyPressed( inDragRef ) ) return;
- if ( ! mModifier && ! mTextDrag ) return;
-
- // Set the current port to this dialog.
- if ( ! FocusDraw() ) return;
-
- // Get the mouse location and convert to port coordinates.
- Point thePoint;
- ::GetDragMouse( inDragRef, &thePoint, NULL );
- GlobalToPortPoint( thePoint );
-
- // If dragging position is in some EditField, then the EditField turns to be hilited.
- PaneIDT thePaneID = FindPaneByMouse( thePoint );
- if ( thePaneID != mHilitePaneID ) HilitePane( thePaneID );
- }
-
-
- // --------------------------------------------------
- // • HiliteDropArea
- // --------------------------------------------------
-
- void
- CTouchMeMainWindow::HiliteDropArea(
- DragReference inDragRef )
- {
- RgnHandle theHiliteRgnH = ::NewRgn();
-
- // I do not know why 'mModifier' is not updated by 'EnterDropArea()'. ???
- // if ( ! IsModifierKeyPressed(inDragRef) ) {
- if ( ! mModifier && ! mTextDrag ) {
-
- // If option-key is not pressed, the hilite region is the dialog bound of rect.
- Rect theRect;
- CalcLocalFrameRect( theRect );
- ::RectRgn( theHiliteRgnH, &theRect );
- FocusDraw(); // 'Focus()' and 'Refresh()' seems to be required here,
- Refresh(); // otherwise the 'ShowDragHilite()' does not work properly.
-
- } else {
-
- // If modifier key is pressed, the hilite region is a union of EditFields.
- RgnHandle theRgnH = ::NewRgn();
- PaneIDT iPaneID;
- // Get hilite region.
- for ( short i=0; (iPaneID=thePaneList[i]) != kNoPaneID; i++ ) {
- Rect theRect;
- LPane *thePane;
- thePane = (LPane *) FindPaneByID( iPaneID );
- thePane->FocusDraw(); // 'Focus()' and 'Refresh()' seems to be required here,
- thePane->Refresh(); // otherwise the 'ShowDragHilite()' does not work properly.
- thePane->CalcPortFrameRect( theRect );
- ::RectRgn( theRgnH, &theRect );
- ::UnionRgn( theHiliteRgnH, theRgnH, theHiliteRgnH );
- }
- ::DisposeRgn( theRgnH );
-
- }
-
- ::ShowDragHilite( inDragRef, theHiliteRgnH, true );
-
- ::DisposeRgn( theHiliteRgnH );
- }
-
-
- // ==================================================
- // Common functions
- // ==================================================
-
- // --------------------------------------------------
- // • IsModifierKeyPressed
- // --------------------------------------------------
-
- Boolean
- CTouchMeMainWindow::IsModifierKeyPressed(
- DragReference inDragRef )
- {
- short theModifiers, theMouseDownModifiers, theMouseUpModifiers;
-
- ::GetDragModifiers( inDragRef,
- &theModifiers, &theMouseDownModifiers, &theMouseUpModifiers );
-
- return (Boolean) ( (theModifiers & (optionKey | cmdKey) ) != 0 );
- }
-
-
- // --------------------------------------------------
- // • FindPaneByMouse
- // --------------------------------------------------
-
- PaneIDT
- CTouchMeMainWindow::FindPaneByMouse(
- const Point inPoint )
- {
- PaneIDT iPaneID;
-
- for ( short i=0; (iPaneID=thePaneList[i]) != kNoPaneID; i++ ) {
- Rect theRect;
- LPane *thePane;
- thePane = (LPane *) FindPaneByID( iPaneID );
- thePane->CalcPortFrameRect( theRect );
- if ( ::PtInRect( inPoint, &theRect ) ) return iPaneID;
- }
-
- return (PaneIDT) kNoPaneID;
- }
-
-
- // --------------------------------------------------
- // • HilitePane
- // --------------------------------------------------
-
- void
- CTouchMeMainWindow::HilitePane(
- const PaneIDT inPaneID )
- {
- // Set the current port to this dialog.
- if ( ! FocusDraw() ) return;
-
- // Restore the previous one.
- if ( mHilitePaneID != kNoPaneID ) {
- LPane * thePane = (LPane *) FindPaneByID( mHilitePaneID );
- Rect theRect;
- thePane->CalcPortFrameRect( theRect );
- HiliteRect( theRect );
- }
-
- if ( inPaneID == mHilitePaneID ) return;
-
- // Setup the present one.
- if ( inPaneID != kNoPaneID ) {
- LPane * thePane = (LPane *) FindPaneByID( inPaneID );
- Rect theRect;
- thePane->CalcPortFrameRect( theRect );
- HiliteRect( theRect );
- }
-
- mHilitePaneID = inPaneID;
- }
-
-
- // --------------------------------------------------
- // • HiliteRect
- // --------------------------------------------------
- #include <LowMem.h>
-
- void
- CTouchMeMainWindow::HiliteRect(
- const Rect & inRect )
- {
- #ifdef COMMENT
- // From "Highlighting" section in p.4-41,
- // Apple Computer's Inside Macintosh "Imaging with QuickDraw".
-
- UInt8 theHiliteMode;
- theHiliteMode = ::LMGetHiliteMode();
- // theHiliteMode &= ~( (UInt8) 0x01 << hiliteBit );
- ::BitClr( &theHiliteMode, pHiliteBit );
- ::LMSetHiliteMode( theHiliteMode );
- #else // COMMENT
- UDrawingUtils::SetHiliteModeOn();
- #endif // COMMENT
-
- ::InvertRect( &inRect );
- }
-
-
- // end of program
-